# coding=utf-8

"""
@Author: LiangChao
@Email: kevinleong1011@hotmail.com
@Desc: 
"""
import traceback
from datetime import datetime
from typing import List

from makitest.task import task
from .log import logger
from .tree import TestNode


class TestFixture:
    def __init__(self, project=None, context=None):
        self.project = project
        self.context = context
        self.name, self.test_name, self.desc = None, None, None
        self._tests: List[TestNode] = []
        self._cur_test = None
        self.total_count = 0
        self.passed_count, self.failed_count, self.blocked_count, self.error_count, self.skipped_count = 0, 0, 0, 0, 0
        self.start_time, self.finish_time, self.time_cost = None, None, 0
        self.logger = logger

    def add_test(self, obj):
        """
        添加测试
        :param obj:
        :return:
        """
        node = TestNode(obj, self.project, self.context, fixture=self)
        node.fixture = self
        self._tests.append(node)
        return node

    def start(self):
        self.start_time = datetime.now()
        self.logger.info(f'Start fixture: {self.test_name}')
        self.project.plugin.on_fixture_start(self, self.context)

    def finish(self):
        self.finish_time = datetime.now()
        self.time_cost = (self.finish_time - self.start_time).seconds
        self.project.plugin.on_fixture_finished(self, self.context)
        self.logger.info(f'Finish fixture: {self.test_name}, cost {self.time_cost}s')

    def run(self):
        self.load_tests()
        self.logger.info(f'Found {self.total_count} tests')
        if self.total_count <= 0:
            return
        try:
            self.start()
            for test in self._tests:
                test.run()
        except Exception:
            self.logger.error(traceback.format_exc())
        finally:
            self.finish()
            self.context.reset()

    def run_async(self):
        t = task.submit(self.run)
        return t

    def load_tests(self):
        for test in self._tests:
            test.load_tests()
            self.total_count += test.count

    def __len__(self):
        return len(self._tests)
